package com.gridmobi.xrtb.component.lucene;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.gridmobi.xrtb.common.BudgetResourcePool;
import com.gridmobi.xrtb.common.CampaignRateLimiter;
import com.gridmobi.xrtb.component.lucene.analyzer.CommaAnalyzer;
import com.gridmobi.xrtb.domain.adn.OsE;
import com.gridmobi.xrtb.domain.dsp.*;
import com.gridmobi.xrtb.domain.dsp.common.AppConstant;
import com.gridmobi.xrtb.domain.dsp.common.Patten;
import com.gridmobi.xrtb.domain.dsp.common.enums.*;
import com.gridmobi.xrtb.handler.monitor.RtbStatus;
import com.gridmobi.xrtb.handler.monitor.SimpleData;
import com.gridmobi.xrtb.model.rtb.Creative;
import com.gridmobi.xrtb.model.rtb.TrdImprDto;
import com.gridmobi.xrtb.routers.Info;
import org.apache.lucene.document.*;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.TermInSetQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.MMapDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.BytesRef;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Stream;

import static com.gridmobi.xrtb.domain.dsp.common.enums.IndexModeE.RAM;


@Component
public class BidIndex {
    public static String CFG_DEFALUT_ALL = (CfgTypeE.INCLUDE.code + AppConstant.SEPARATOR + AppConstant.DEFAULT_CFGV).toLowerCase();
    @Value("${luceneindex.synch.stoponerror}")
    private Integer stopOnError = Integer.MAX_VALUE;


    private Integer buffer = 512;
    /**
     * 索引模式 ram 为纯内存模式
     */
    private String indexModel = "ram";

    private static final Logger logger = LoggerFactory.getLogger(BidIndex.class);
    /**
     * 活动基础配置索引
     */
    public static IndexWriter CAMPAIGNS_W;
    /**
     * banner素材索引
     */
    public static IndexWriter CREATIVES_W;

    public static IndexWriter CREATIVES_NATIVE_W;
    /**
     * 活动定向配置索引
     */
    public static IndexWriter CAMPAIGNS_CFGS_W;
    /**
     * 活动投放时段索引
     */
    public static IndexWriter CAMPAIGNS_SCHE_W;


    public static Directory CAMPAIGNS_DIR;
    public static Directory CREATIVES_DIR;
    public static Directory CREATIVES_NATIVE_DIR;

    public static Directory CAMPAIGNS_SCHE_DIR;

    public static Map<String, IndexWriter> INDEX_W_MAP;

    public volatile Map<Integer, List<Creative>> creativeMap = new HashMap<>();


    public BidIndex() {
        try {
            if (RAM.key.equals(indexModel)) {
                CAMPAIGNS_DIR = new RAMDirectory();
                CREATIVES_DIR = new RAMDirectory();
                CREATIVES_NATIVE_DIR = new RAMDirectory();
                CAMPAIGNS_SCHE_DIR = new RAMDirectory();
            } else {
                CAMPAIGNS_DIR = new MMapDirectory(Paths.get("./idxcampaigns"));
                CREATIVES_DIR = new MMapDirectory(Paths.get("./idxbanner"));
                CREATIVES_NATIVE_DIR = new MMapDirectory(Paths.get("./idxnative"));
                CAMPAIGNS_SCHE_DIR = new MMapDirectory(Paths.get("./idxcampaignsche"));
            }

            IndexWriterConfig iwc1 = new IndexWriterConfig(new CommaAnalyzer());
            iwc1.setRAMBufferSizeMB(Optional.ofNullable(buffer).orElse(256));
            IndexWriterConfig iwc2 = new IndexWriterConfig(new CommaAnalyzer());
            iwc2.setRAMBufferSizeMB(Optional.ofNullable(buffer).orElse(256));

            IndexWriterConfig iwc5 = new IndexWriterConfig(new CommaAnalyzer());
            iwc5.setRAMBufferSizeMB(Optional.ofNullable(buffer).orElse(256));


            IndexWriterConfig iwc3 = new IndexWriterConfig(new CommaAnalyzer());
            iwc3.setRAMBufferSizeMB(Optional.ofNullable(buffer).orElse(256));
            IndexWriterConfig iwc4 = new IndexWriterConfig(new CommaAnalyzer());
            iwc4.setRAMBufferSizeMB(20);


            logger.info("Lucene Index define  MMap Buffer Size :" + Optional.ofNullable(buffer).orElse(256));
            CAMPAIGNS_W = new IndexWriter(CAMPAIGNS_DIR, iwc1);
            CREATIVES_W = new IndexWriter(CREATIVES_DIR, iwc2);
            CREATIVES_NATIVE_W = new IndexWriter(CREATIVES_NATIVE_DIR, iwc5);

            CAMPAIGNS_SCHE_W = new IndexWriter(CAMPAIGNS_SCHE_DIR, iwc4);
            INDEX_W_MAP = new HashMap<>(4);
            INDEX_W_MAP.put(Info.CAMPAIGNS, CAMPAIGNS_W);
            INDEX_W_MAP.put(Info.SCHS, CAMPAIGNS_SCHE_W);
            INDEX_W_MAP.put(Info.NATIVE, CREATIVES_NATIVE_W);
            INDEX_W_MAP.put(Info.BANNERS, CREATIVES_W);

            logger.info("Lucene Index define finish");

        } catch (Exception e) {
            logger.error("Lucene Index define ! exit !", e);
            System.exit(0);
        }
    }

    public void indexCampaigns(List datas) {
        try {
            CAMPAIGNS_W.deleteAll();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (CollectionUtils.isEmpty(datas)) {
            return;
        }
        BudgetResourcePool.initLimiter(datas);
//        CampaignRateLimiter.initLimiter(datas);
        datas.forEach(n -> {
            DspCampaigns c = JSONObject.parseObject(JSONObject.toJSONString(n), DspCampaigns.class);

            if (StateE.VALID.code == c.getState() && DelFlagE.NO.code == c.getDeleteflag() && (c.getBudgetdaily() > c.getCurrentdailybudget())) {
                SimpleData.BUDGET_ACTI_CAMPAIGN.add(c.getId().toString());
            } else {
                SimpleData.BUDGET_FULL_CAMPAIGN.add(c.getId().toString());
            }
        });
        logger.warn("ACTIC:" + JSONObject.toJSONString(SimpleData.BUDGET_ACTI_CAMPAIGN));
        logger.warn("ACTIC UN:" + JSONObject.toJSONString(SimpleData.BUDGET_FULL_CAMPAIGN));

        LocalDateTime now = LocalDateTime.now();
        String day = now.format(DateTimeFormatter.ofPattern(Patten.DATE));

        try {
            List<DspCfgList> schList = new LinkedList<>();
            datas.forEach(n -> {
                try {
                    DspCampaigns c = JSONObject.parseObject(JSONObject.toJSONString(n), DspCampaigns.class);
                    SimpleData.CAMPAIGNS_LANDURL.put(c.getId().toString(), c.getLandingurl());

                    Document doc = new Document();
                    SimpleData.CAMPAIGNS_DAYLY_BUDGET_CACHE.put(c.getId(), c.getBudgetdaily());
                    doc.add(new StringField("id", c.getId().toString(), Field.Store.YES));
                    doc.add(new StringField("state", c.getState().toString(), Field.Store.YES));
                    doc.add(new StringField("deleteflag", c.getDeleteflag().toString(), Field.Store.YES));
                    doc.add(new StringField("aid", c.getAid().toString(), Field.Store.YES));
                    doc.add(new TextField("inventorytype", InventoryTypeE.getOtherV(c.getInventorytype()), Field.Store.YES));
                    doc.add(new StringField("labelid", c.getLabelid().toString(), Field.Store.YES));
                    doc.add(new StringField("cname", defaultV(c.getCname()), Field.Store.YES));
                    doc.add(new StringField("landingurl", c.getLandingurl(), Field.Store.YES));
                    doc.add(new StringField("urlsecured", String.valueOf(c.getUrlsecured()), Field.Store.YES));
                    doc.add(new TextField("exchanges", c.getExchanges().toLowerCase(), Field.Store.YES));
                    doc.add(new TextField("iabcats", defaultV(c.getIabcats()), Field.Store.YES));
                    doc.add(new StringField("buyingstrategy", c.getBuyingstrategy(), Field.Store.YES));
                    doc.add(new FloatPoint("buyingprice", c.getBuyingprice()));
                    doc.add(new StoredField("buyingprice", c.getBuyingprice()));
                    doc.add(new TextField("environment", c.getEnvironment(), Field.Store.YES));
                    doc.add(new FloatPoint("budgetdaily", c.getBudgetdaily()));
                    doc.add(new StoredField("budgetdaily", c.getBudgetdaily()));
                    if (c.getBudgetdaily() == null && c.getBudgetdaily() > 100) {
                        return;
                    } else {
                    }
                    doc.add(new StringField("advdomain", c.getAdvdomain(), Field.Store.YES));
                    doc.add(new FloatPoint("budgetall", c.getBudgetall()));
                    doc.add(new StoredField("budgetall", c.getBudgetall()));
                    doc.add(new IntPoint("pacingtype", c.getPacingtype()));
                    doc.add(new StoredField("pacingtype", c.getPacingtype()));
                    doc.add(new IntPoint("dailyfrequenceuser", c.getDailyfrequenceuser()));
                    doc.add(new StoredField("dailyfrequenceuser", c.getDailyfrequenceuser()));
                    if (StringUtils.isEmpty(c.getFrequencytype())) {
                        c.setFrequencytype(FrequencyTypeE.CONTAINSIDFA.key);
                    }
                    doc.add(new TextField("frequencytype", c.getFrequencytype(), Field.Store.YES));
                    doc.add(new TextField("targetingos", OsE.getOtherV(c.getTargetingos()), Field.Store.YES));
                    doc.add(new TextField("devicetype", DeviceTypeE.getOtherV(c.getDevicetype()), Field.Store.YES));
                    doc.add(new TextField("connectiontype", ConnectTypeE.getOtherV(c.getConnectiontype()), Field.Store.YES));
                    doc.add(new TextField("revenuetype", c.getRevenuetype(), Field.Store.YES));
                    doc.add(new FloatPoint("revenuevalue", c.getRevenuevalue()));
                    doc.add(new StoredField("revenuevalue", c.getRevenuevalue()));
                    if (!StringUtils.isEmpty(c.getAdvappbundle())) {
                        doc.add(new StringField("advappbundle", c.getAdvappbundle(), Field.Store.YES));
                        SimpleBidData.CAMPAIGN_APPBUNDLE.put(c.getId().toString(), c.getAdvappbundle());
                    }
                    if (!StringUtils.isEmpty(c.getAppstoreurl())) {
                        doc.add(new StringField("appstoreurl", c.getAppstoreurl(), Field.Store.YES));
                        SimpleBidData.CAMPAIGN_APPSTOREURL.put(c.getId().toString(), c.getAppstoreurl());
                    }

                    if (!StringUtils.isEmpty(c.getImprurl())) {
                        doc.add(new StringField("imprurl", c.getImprurl(), Field.Store.YES));
                        if (c.getImprurl() != null && c.getImprurl().indexOf("-") > 0) {
                            String[] ss = c.getImprurl().split("-");
                            TrdImprDto trdImprDto = new TrdImprDto();
                            trdImprDto.setCnt(Integer.parseInt(ss[0]));
                            trdImprDto.setLandurl(ss[1]);
                            SimpleBidData.LAND_URL_TRD.put(c.getId().toString(), trdImprDto);
                        }

                    }


                    Float iosminiv = 1f;
                    Float iosmaxv = 100f;
                    Float androidminv = 1f;
                    Float androidmaxv = 100f;

                    if (c.getIososv() != null) {
                        String[] vers = c.getIososv().split("_");
                        if (vers.length == 2) {
                            iosminiv = Float.parseFloat(vers[0]);
                            iosmaxv = Float.parseFloat(vers[1]);
                        }

                    }

                    if (c.getAndroidosv() != null) {
                        String[] vers = c.getAndroidosv().split("_");
                        if (vers.length == 2) {
                            androidminv = Float.parseFloat(vers[0]);
                            androidmaxv = Float.parseFloat(vers[1]);
                        }
                    }

                    doc.add(new FloatPoint("iosminiv", iosminiv));
                    doc.add(new StoredField("iosminiv", iosminiv));
                    doc.add(new FloatPoint("iosmaxv", iosmaxv));
                    doc.add(new StoredField("iosmaxv", iosmaxv));
                    doc.add(new FloatPoint("andoridminiv", androidminv));
                    doc.add(new StoredField("andoridminiv", androidminv));
                    doc.add(new FloatPoint("andoridmaxv", androidmaxv));
                    doc.add(new StoredField("andoridmaxv", androidmaxv));

                    if (c.getCfs() != null) {
                        /**
                         * 不存在定向的配置 默认都是全部
                         */
                        cfgvDefault(c.getCfs());

                        c.getCfs().forEach((k, v) -> {
                            if (CfgKeyE.TARGETING_SCHEDULE.key.equals(k)) {
                                DspCfgList dspCfgList = new DspCfgList();
                                dspCfgList.setCid(c.getId().intValue());
                                dspCfgList.setCfgvalue(v);
                                schList.add(dspCfgList);
                                doc.add(new StringField(k, v, Field.Store.YES));

                            } else if (CfgKeyE.CREATIVES.key.equals(k)) {
                                doc.add(new TextField(k, v, Field.Store.YES));
                            } else {
                                if (v.indexOf(CFG_DEFALUT_ALL) < 0 && v.indexOf(CfgTypeE.EXCLUDE.code + AppConstant.SEPARATOR) >= 0) {
                                    v = v.concat(",").concat(CFG_DEFALUT_ALL);
                                }

                                doc.add(new TextField(k, v, Field.Store.YES));

                                /**
                                 * 如果活动激活 记录 GEO 活动下线  删除该活动GEO
                                 * BID请求 来的时候 判断GEO 是否在 激活活动列表里
                                 */
                                if (CfgKeyE.TARGETING_COUNTRIES.key.equals(k)) {
                                    if (StateE.VALID.code == c.getState() && DelFlagE.NO.code == c.getDeleteflag()) {
                                        String[] cs = v.replace(CfgTypeE.INCLUDE.code + AppConstant.SEPARATOR, "").toUpperCase().split(",");
                                        SimpleData.CAMPAIGNS_TARGET_COUNTRY.addAll(Arrays.asList(cs));
                                    }
                                }
                            }
                        });
                    }
                    CAMPAIGNS_W.updateDocument(new Term("id", c.getId().toString()), doc);
                    /**
                     * 单独缓存活动的landurl 后面click跳转时候比较容易获取
                     */

                    CAMPAIGNS_W.commit();


                } catch (IOException e) {
                    RtbStatus.errorCounter();
                    logger.error("Lucene Index Add Doc Error".concat(n.toString()), e);
                    try {
                        CAMPAIGNS_W.rollback();
                    } catch (IOException e1) {
                        logger.error("Lucene Index Rollback Error", e);
                    }
                }
                indexTargetingSchedule(schList);
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void mapCreatives(List<Creative> datas) {
        Map<Integer, List<Creative>> tmpCreativeMap = new HashMap<>();
        for (Creative data : datas) {
            List<Integer> cids = data.getCids();
            if (CollectionUtils.isEmpty(cids)) {
                continue;
            }
            putImageMap(tmpCreativeMap, cids, data);
        }

        creativeMap = tmpCreativeMap;

    }

    private void putImageMap(Map<Integer, List<Creative>> tmpCreativeMap, List<Integer> cids, Creative creative) {
        for (Integer cid : cids) {
            List<Creative> creatives = tmpCreativeMap.get(cid);
            if (creatives == null) {
                creatives = new ArrayList<>();
                tmpCreativeMap.put(cid, creatives);
            }
            creatives.add(creative);

        }
    }

    public Creative getCreative(Integer cid, Integer w, Integer h) {
        if (CollectionUtils.isEmpty(creativeMap)) {
            return null;
        }
        List<Creative> creatives = creativeMap.get(cid);
        if (CollectionUtils.isEmpty(creatives)) {
            return null;
        }
        List<Creative> matchedCreative = new ArrayList<>();
        for (Creative creative : creatives) {
            if ((creative.getW() % w == 0 && creative.getH() % h == 0) || (w % creative.getW() == 0 && h % creative.getH() == 0)) {
                matchedCreative.add(creative);
            }
        }

        if (CollectionUtils.isEmpty(matchedCreative)) {
            return null;
        }
        Random random = new Random();
        int i = random.nextInt(matchedCreative.size());
        return matchedCreative.get(i);
    }


    public void indexCreatives(List<Creative> datas) {
        if (CollectionUtils.isEmpty(datas)) {
            return;
        }
        mapCreatives(datas);

        try {
            datas.forEach(c -> {
                try {
                    Document doc = new Document();
                    doc.add(new StringField("id", c.getId().toString(), Field.Store.YES));
                    doc.add(new StringField("state", c.getState().toString(), Field.Store.YES));
                    doc.add(new StringField("deleteflag", c.getDeleteflag().toString(), Field.Store.YES));
                    doc.add(new StringField("mime", c.getMime(), Field.Store.YES));
                    doc.add(new IntPoint("videoduration", c.getVideoduration()));
                    doc.add(new IntPoint("w", c.getW()));
                    doc.add(new IntPoint("h", c.getH()));
                    doc.add(new StoredField("videoduration", c.getVideoduration()));
                    doc.add(new StoredField("w", c.getW()));
                    doc.add(new StoredField("h", c.getH()));
                    doc.add(new StringField("type", c.getType().toString(), Field.Store.YES));
                    doc.add(new StringField("size", c.getW() + "x" + c.getH(), Field.Store.YES));
                    if (CreativeTypeE.VIDEO.code == c.getType()) {
                        /*
                        如果是视频 增加视频的 bytesize 单位为 byte
                         */
//                        doc.add(new LongPoint("bsize", c.getBsize()));
//                        doc.add(new StoredField("bsize", c.getBsize()));
                    }
                    if (StringUtils.isEmpty(c.getUrl())) {
                        return;
                    }
                    doc.add(new StringField("url", Optional.ofNullable(c.getUrl()).orElse(""), Field.Store.YES));
                    String cids = Optional.ofNullable(c.getCids()).orElse(new LinkedList<>()).toString().replace("[", "").replace("]", "");
                    doc.add(new TextField("cid", org.apache.commons.lang3.StringUtils.deleteWhitespace(cids), Field.Store.YES));
                    CREATIVES_W.updateDocument(new Term("id", c.getId().toString()), doc);

                } catch (IOException e) {
                    RtbStatus.errorCounter();
                    logger.error("Lucene Index Cfg Doc Error".concat(JSONObject.toJSONString(c)), e);
                    try {
                        CREATIVES_W.rollback();
                    } catch (IOException e1) {
                        logger.error("Lucene Index Rollback Error", e);
                    }
                }
            });

        } catch (Exception e) {
            logger.error("Lucene Index Cfg Doc Error", e);
        }

    }


    public void indexCreativesNative(List<DspCreativeNative> datas) {
        if (CollectionUtils.isEmpty(datas)) {
            return;
        }

        try {
            datas.forEach(c -> {
                try {
                    Document doc = new Document();


                    doc.add(new StringField("id", CreativeTypeE.NATIVE.code + AppConstant.URL_SEPARATOR + c.getId(), Field.Store.YES));
                    doc.add(new StringField("state", c.getState().toString(), Field.Store.YES));
                    doc.add(new StringField("deleteflag", c.getDeleteflag().toString(), Field.Store.YES));
                    if (c.getVideoduration() != null) {

                        doc.add(new IntPoint("videoduration", c.getVideoduration()));
                        doc.add(new StoredField("videoduration", c.getVideoduration()));
                    }
                    if (c.getAdrating() != null) {

                        doc.add(new IntPoint("adrating", c.getAdrating()));
                        doc.add(new StoredField("adrating", c.getAdrating()));
                    }
                    if (c.getAdlikes() != null) {

                        doc.add(new IntPoint("adlikes", c.getAdlikes()));
                        doc.add(new StoredField("adlikes", c.getAdlikes()));
                    }


                    if (c.getIconw() != null) {
                        doc.add(new IntPoint("iconw", c.getIconw()));
                        doc.add(new IntPoint("iconh", c.getIconh()));
                        doc.add(new StoredField("iconh", c.getIconh()));
                        doc.add(new StoredField("iconw", c.getIconw()));
                    }
                    if (c.getImgw() != null) {
                        doc.add(new IntPoint("imgw", c.getImgw()));
                        doc.add(new IntPoint("imgh", c.getImgh()));
                        doc.add(new StoredField("imgw", c.getImgw()));
                        doc.add(new StoredField("imgh", c.getImgh()));
                    }
                    if (c.getLarimgw() != null) {
                        doc.add(new IntPoint("larimgw", c.getLarimgw()));
                        doc.add(new IntPoint("larimgh", c.getLarimgh()));
                        doc.add(new StoredField("larimgh", c.getLarimgh()));
                        doc.add(new StoredField("larimgw", c.getLarimgw()));
                    }
                    if (c.getVideow() != null) {
                        doc.add(new IntPoint("videow", c.getVideow()));
                        doc.add(new IntPoint("videoh", c.getVideoh()));
                        doc.add(new StoredField("videoh", c.getVideoh()));
                        doc.add(new StoredField("videow", c.getVideow()));
                    }
                    if (c.getIconweburl() != null) {

                        doc.add(new StringField("iconweburl", c.getIconweburl(), Field.Store.YES));
                    }
                    if (c.getIconweburl() != null) {

                        doc.add(new StringField("imgweburl", c.getImgweburl(), Field.Store.YES));
                    }
                    if (c.getLargeimgurl() != null) {

                        doc.add(new StringField("largeimgurl", c.getLargeimgurl(), Field.Store.YES));
                    }
                    if (c.getVideoweburl() != null) {

                        doc.add(new StringField("videoweburl", c.getVideoweburl(), Field.Store.YES));
                    }
                    if (c.getVideomimes() != null) {

                        doc.add(new StringField("videomimes", c.getVideomimes(), Field.Store.YES));
                    }
                    if (c.getAdsponsored() != null) {

                        doc.add(new StringField("adsponsored", c.getAdsponsored(), Field.Store.YES));
                    }
                    if (c.getAdtitle() != null) {

                        doc.add(new StringField("adtitle", c.getAdtitle(), Field.Store.YES));
                    }
                    if (c.getAddesc() != null) {

                        doc.add(new StringField("addesc", c.getAddesc(), Field.Store.YES));
                    }

                    if (c.getAppbundle() != null) {

                        doc.add(new StringField("appbundle", c.getAppbundle(), Field.Store.YES));
                    }
                    if (c.getActiontext() != null) {

                        doc.add(new StringField("actiontext", c.getActiontext(), Field.Store.YES));
                    }
                    if (c.getCountries() != null) {

                        doc.add(new TextField("countries", c.getCountries(), Field.Store.YES));
                    }
                    if (c.getCids() != null) {

                        String cids = Optional.ofNullable(c.getCids()).orElse(new LinkedList<>()).toString().replace("[", "").replace("]", "");
                        doc.add(new TextField("cid", org.apache.commons.lang3.StringUtils.deleteWhitespace(cids), Field.Store.YES));
                    }
                    CREATIVES_NATIVE_W.updateDocument(new Term("id", CreativeTypeE.NATIVE.code + AppConstant.URL_SEPARATOR + c.getId()), doc);

                } catch (IOException e) {
                    RtbStatus.errorCounter();
                    logger.error("Lucene Index Natives Doc Error".concat(JSONObject.toJSONString(c)), e);
                    try {
                        CREATIVES_NATIVE_W.rollback();
                    } catch (IOException e1) {
                        logger.error("Lucene Index Rollback Error", e);
                    }
                }
            });

        } catch (Exception e) {
            logger.error("Lucene Index Cfg Doc Error", e);
        }


    }


    public void indexMicroBid(List datas) {
        if (CollectionUtils.isEmpty(datas)) {
            return;
        }

        try {
            datas.forEach(n -> {
                DspMicroBidding c = JSONObject.parseObject(JSONObject.toJSONString(n), DspMicroBidding.class);
                final String key = c.getCid().toString().concat(AppConstant.SEPARATOR).concat(c.getMicrotype().toString()).concat(AppConstant.SEPARATOR).concat(c.getMicrovalue());
                if (StateE.VALID.code == c.getState() && DelFlagE.NO.code == c.getDeleteflag()) {
                    SimpleBidData.MICRO_BID.put(key, c.getCpmbid());
                } else {
                    SimpleBidData.MICRO_BID.remove(key);
                }
            });

        } catch (Exception e) {
            logger.error("Lucene Index Cfg Doc Error", e);
        }


    }

    /**
     * blocktype
     *
     * @param datas
     * @see ReportGroupE
     */
    public void indexBlockList(List datas) {
        if (CollectionUtils.isEmpty(datas)) {
            return;
        }

        try {
            datas.forEach(n -> {
                DspBlocklist c = JSONObject.parseObject(JSONObject.toJSONString(n), DspBlocklist.class);
                final String key = c.getBlocktype().toString().concat(AppConstant.SEPARATOR).concat(c.getBlockvalue());
                if (StateE.VALID.code == c.getState() && DelFlagE.NO.code == c.getDeleteflag()) {
                    SimpleBidData.BLOCK_LIST.add(key);
                } else {
                    SimpleBidData.BLOCK_LIST.remove(key);
                }
            });

        } catch (Exception e) {
            logger.error("Lucene Index Cfg Doc Error", e);
        }


    }


    public static void cfgvDefault(Map j) {
        if (!j.containsKey(CfgKeyE.INVENTORY_APPBUNDLES.key)) {
            j.put(CfgKeyE.INVENTORY_APPBUNDLES.key, CFG_DEFALUT_ALL);
        }
        if (!j.containsKey(CfgKeyE.TARGETING_COUNTRIES.key)) {
            j.put(CfgKeyE.TARGETING_COUNTRIES.key, CFG_DEFALUT_ALL);

        }
        if (!j.containsKey(CfgKeyE.TARGETING_CARRIERS.key)) {
            j.put(CfgKeyE.TARGETING_CARRIERS.key, CFG_DEFALUT_ALL);

        }
        if (!j.containsKey(CfgKeyE.INVENTORY_PUBLISHERS.key)) {
            j.put(CfgKeyE.INVENTORY_PUBLISHERS.key, CFG_DEFALUT_ALL);

        }
        if (!j.containsKey(CfgKeyE.TARGETING_IPRANGES.key)) {
            j.put(CfgKeyE.TARGETING_IPRANGES.key, CFG_DEFALUT_ALL);

        }
        if (!j.containsKey(CfgKeyE.TARGETING_DEVICEMODEL.key)) {
            j.put(CfgKeyE.TARGETING_DEVICEMODEL.key, CFG_DEFALUT_ALL);

        }
        if (!j.containsKey(CfgKeyE.TARGETING_DEVICEID.key)) {
            j.put(CfgKeyE.TARGETING_DEVICEID.key, CFG_DEFALUT_ALL);

        }
        if (!j.containsKey(CfgKeyE.INVENTORY_DOMAINLIST.key)) {
            j.put(CfgKeyE.INVENTORY_DOMAINLIST.key, CFG_DEFALUT_ALL);

        }
        if (!j.containsKey(CfgKeyE.INVENTORY_APPSITE.key)) {
            j.put(CfgKeyE.INVENTORY_APPSITE.key, CFG_DEFALUT_ALL);

        }
        if (!j.containsKey(CfgKeyE.TARGETING_CITIES.key)) {
            j.put(CfgKeyE.TARGETING_CITIES.key, CFG_DEFALUT_ALL);

        }
        if (!j.containsKey(CfgKeyE.INVENTORY_APPIABCATEGORY.key)) {
            j.put(CfgKeyE.INVENTORY_APPIABCATEGORY.key, CFG_DEFALUT_ALL);

        }
        if (!j.containsKey(CfgKeyE.INVENTORY_APPSTORECATEGORY.key)) {
            j.put(CfgKeyE.INVENTORY_APPSTORECATEGORY.key, CFG_DEFALUT_ALL);

        }

    }

    public void indexTargetingSchedule(List<DspCfgList> datas) {
        try {
            datas.forEach(c -> {
                JSONArray schs = JSONObject.parseArray(c.getCfgvalue());
                try {
                    CAMPAIGNS_SCHE_W.deleteDocuments(new Term("cid", c.getCid().toString()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                schs.forEach(sch -> {

                    try {
                        JSONObject s = (JSONObject) sch;
                        if (s.getInteger("st") > s.getInteger("et")) {

                            Document doc = new Document();
                            doc.add(new StringField("cid", c.getCid().toString(), Field.Store.YES));
                            doc.add(new TextField("d", s.getString("sch").replace("[", "").replace("]", ""), Field.Store.YES));
                            doc.add(new IntPoint("st", 0));
                            doc.add(new StoredField("st", 0));
                            doc.add(new IntPoint("et", s.getInteger("et")));
                            doc.add(new StoredField("et", s.getInteger("et")));
                            CAMPAIGNS_SCHE_W.addDocument(doc);
                            CAMPAIGNS_SCHE_W.commit();

                            Document doc1 = new Document();
                            doc1.add(new StringField("cid", c.getCid().toString(), Field.Store.YES));
                            doc1.add(new TextField("d", s.getString("sch").replace("[", "").replace("]", ""), Field.Store.YES));
                            doc1.add(new IntPoint("st", s.getInteger("st")));
                            doc1.add(new StoredField("st", s.getInteger("st")));
                            doc1.add(new IntPoint("et", 23));
                            doc1.add(new StoredField("et", 23));
                            CAMPAIGNS_SCHE_W.addDocument(doc1);
                            CAMPAIGNS_SCHE_W.commit();


                        } else {
                            Document doc = new Document();
                            doc.add(new StringField("cid", c.getCid().toString(), Field.Store.YES));
                            doc.add(new TextField("d", s.getString("sch").replace("[", "").replace("]", ""), Field.Store.YES));
                            doc.add(new IntPoint("st", s.getInteger("st")));
                            doc.add(new StoredField("st", s.getInteger("st")));
                            doc.add(new IntPoint("et", s.getInteger("et")));
                            doc.add(new StoredField("et", s.getInteger("et")));
                            CAMPAIGNS_SCHE_W.addDocument(doc);
                            CAMPAIGNS_SCHE_W.commit();
                        }

                    } catch (IOException e) {
                        RtbStatus.errorCounter();
                        logger.error("Lucene Index Sch Doc Error" + c.getCid(), e);
                        try {
                            CAMPAIGNS_SCHE_W.rollback();
                        } catch (IOException e1) {
                            logger.error("Lucene Index Rollback Error", e);
                        }
                    }
                });


            });
        } catch (Exception e) {
            logger.error("Lucene Index Sch Doc Error", e);
        }


    }


    private String defaultV(String v) {
        return Optional.ofNullable(v).orElse("N/A");
    }

    public static JSONObject doc2Json(Document doc) {

        return BidIndex.doc2Json(doc, null);
    }


    public static void buildCfgQuery(BooleanQuery.Builder builder, String v, String cfgKey) {
        if (!StringUtils.isEmpty(v)) {
            List<BytesRef> cfs = Lists.newArrayList();
            cfs.add(new BytesRef(CFG_DEFALUT_ALL));
            Arrays.stream(v.split("[, /n]")).forEach(pub -> {
                cfs.add(new BytesRef(CfgTypeE.INCLUDE.code + AppConstant.SEPARATOR + pub.toLowerCase()));
            });
            builder.add(new TermInSetQuery(cfgKey, cfs), BooleanClause.Occur.MUST);


            List<BytesRef> cfsex = Lists.newArrayList();
            Arrays.stream(v.split("[, /n]")).forEach(pub -> {
                cfsex.add(new BytesRef(CfgTypeE.EXCLUDE.code + AppConstant.SEPARATOR + pub.toLowerCase()));
            });
            builder.add(new TermInSetQuery(cfgKey, cfsex), BooleanClause.Occur.MUST_NOT);

        }

    }

    public static void buildCfgQueryByMutilValue(BooleanQuery.Builder builder, String[] values, String cfgKey) {
        if (values != null && values.length > 0) {

            List<BytesRef> cfs = new LinkedList<>();
            cfs.add(new BytesRef(CFG_DEFALUT_ALL));
            List<BytesRef> cfsExclued = new LinkedList<>();

            for (String v : values) {
                cfs.add(new BytesRef(CfgTypeE.INCLUDE.code + AppConstant.SEPARATOR + v.toLowerCase()));
                cfsExclued.add(new BytesRef(CfgTypeE.EXCLUDE.code + AppConstant.SEPARATOR + v.toLowerCase()));
            }

            builder.add(new TermInSetQuery(cfgKey, cfs), BooleanClause.Occur.MUST);
            builder.add(new TermInSetQuery(cfgKey, cfsExclued), BooleanClause.Occur.MUST_NOT);
        }

    }

    public static JSONObject doc2Json(Document doc, String... fields) {
        JSONObject jsonObject = new JSONObject();
        if (fields != null) {
            Stream.of(fields).forEach(n -> jsonObject.put(n, doc.get(n)));
        } else {
            doc.getFields().forEach(n -> jsonObject.put(n.name(), doc.get(n.name())));
        }
        return jsonObject;
    }

    public static void main(String[] args) {
        String osv = "12.1.0.1";
        if (!org.apache.commons.lang3.StringUtils.isBlank(osv)) {
            String[] osva = osv.split("\\.");
            if (osva.length == 1) {
                osv = osva[0];
            }
            if (osva.length >= 2) {
                osv = new StringBuffer().append(osva[0]).append(".").append(osva[1]).toString();
            }
        }
        System.out.println("Pegipegi provides an easy-to-use online reservation service for flight tickets, hotels, and train tickets.".length());
        System.out.println(Float.parseFloat(osv));
    }

}
